package design.pattern.application.specifications;

import lombok.Data;

import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * @program JavaBase
 * @description:
 * @author: zhanglu
 * @create: 2030-05-24 14:58:00
 */
public class SpecificationsPatten03 {

    public static void main(String[] args) {
//        //首先初始化一批用户
//        ArrayList<User03> userList = new ArrayList<User03>();
//        userList.add(new User03("苏国庆",23));
//        userList.add(new User03("国庆牛",82));
//        userList.add(new User03("张国庆三",10));
//        userList.add(new User03("李四",10));
//        //定义一个用户查询类
//        IUserProvider03 userProvider = new UserProvider03(userList); //打印出名字包含"国庆"的人员 System.out.println("===名字包含国庆的人员==="); //定义一个规格书
//        IUserSpecification03 spec = new UserByAgeThen03(25);
//        IUserSpecification03 spec2 = new UserByNameLike03("%国庆%");
//        for(User03 u:userProvider.findUser(spec.and(spec2))){
//            System.out.println(u);
//        }

        Pattern p = Pattern.compile("a*b");
        Matcher m = p.matcher("aaaab");
        boolean b = m.matches();
        System.out.println(b);

    }

}

//用户类
@Data
class User03{
    private String name;
    private int age;
    public User03(String name, int age) {
        this.name = name;
        this.age = age;
    }
}

//用户操作对象接口
interface IUserProvider03{
    //根据条件查找用户
    List<User03> findUser(IUserSpecification03 userSpecification03);
}

//规格书接口
interface IUserSpecification03{
    //是否满足要求
    boolean isSatisfiedBy(User03 user);
    //and操作
    IUserSpecification03 and(IUserSpecification03 spec);
    //or操作
    IUserSpecification03 or(IUserSpecification03 spec);
    //not操作
    IUserSpecification03 not();
}
//组合规格书
abstract class CompositeSpecification03 implements IUserSpecification03{
    public abstract boolean isSatisfiedBy(User03 user);
    public IUserSpecification03 and(IUserSpecification03 spec){
        return new AndSpecification(this, spec);
    }
    public IUserSpecification03 or(IUserSpecification03 spec){
        return new OrSpecification(this, spec);
    }
    public IUserSpecification03 not(){
        return new NotSpecification(this);
    }
}
class AndSpecification extends CompositeSpecification03{
    private IUserSpecification03 left;
    private IUserSpecification03 right;
    public AndSpecification(IUserSpecification03 left, IUserSpecification03 right){
        this.left = left;
        this.right = right;
    }
    @Override
    public boolean isSatisfiedBy(User03 user) {
        return left.isSatisfiedBy(user) && right.isSatisfiedBy(user);
    }
}
class OrSpecification extends CompositeSpecification03{
    private IUserSpecification03 left;
    private IUserSpecification03 right;
    public OrSpecification(IUserSpecification03 left, IUserSpecification03 right){
        this.left = left;
        this.right = right;
    }
    @Override
    public boolean isSatisfiedBy(User03 user) {
        return left.isSatisfiedBy(user) || right.isSatisfiedBy(user);
    }
}
class NotSpecification extends CompositeSpecification03{
    private IUserSpecification03 spec;
    public NotSpecification(IUserSpecification03 spec){
        this.spec = spec;
    }
    @Override
    public boolean isSatisfiedBy(User03 user) {
        return !spec.isSatisfiedBy(user);
    }
}
class UserByNameEq03 extends CompositeSpecification03{
    private String name;
    public UserByNameEq03(String name){
        this.name = name;
    }
    @Override
    public boolean isSatisfiedBy(User03 user) {
        return user.getName().equals(name);
    }
}

class UserByAgeThen03 extends CompositeSpecification03{
    private int age;
    public UserByAgeThen03(int age){
        this.age = age;
    }
    @Override
    public boolean isSatisfiedBy(User03 user) {
        return user.getAge() > age;
    }
}
class UserByNameLike03 extends CompositeSpecification03 {
    //like的标记
    private final static String LIKE_FLAG = "%"; //基准的like字符串
    private String likeStr;
    //构造函数传递基准姓名
    public UserByNameLike03(String _likeStr){
        this.likeStr = _likeStr;
    }
    @Override
    public boolean isSatisfiedBy(User03 user) {
        boolean result = false;
        String name = user.getName();
        //替换掉%后的干净字符串
        String str = likeStr.replace("%","");
        //是以名字开头，如'国庆%'
        if(likeStr.endsWith(LIKE_FLAG) && !likeStr.startsWith(LIKE_FLAG)){
            result = name.startsWith(str);
        }else if(likeStr.startsWith(LIKE_FLAG) && !likeStr.endsWith(LIKE_FLAG)){
                result = name.endsWith(str);
        }else{
            result = name.contains(str); //类似于'%国庆%'
        }
        return result;
    }
}
class UserProvider03 implements IUserProvider03{
    private List<User03> userList = new ArrayList<>();
    public UserProvider03(List<User03> userList){
        this.userList = userList;
    }
    @Override
    public List<User03> findUser(IUserSpecification03 userSpecification03) {
        return userList.stream().filter(o -> userSpecification03.isSatisfiedBy(o)).collect(Collectors.toList());
    }
}